{"componentChunkName":"component---node-modules-gatsby-theme-chronoblog-src-templates-post-js","path":"/accessibility-testing-with-nightwatchjs/","result":{"data":{"mdx":{"id":"dce55945-37a4-54cd-9760-44deaccb9a6e","excerpt":"Web Content Accesibility Guidelines and the ADA Testing for compliance with web content accessibility guidelines or WCAG is becoming…","frontmatter":{"title":"Automated web accessibility testing with Nightwatch.js and axe","date":"2020-01-20T00:00:00.000Z","description":"There are quite a few web accessibility testing tools out there, but I thought I'd see if any could fit in with my existing automated Nightwatch tests.","tags":["quality assurance","accessibility testing","software testing","nightwatchjs","post"],"cover":{"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB30lEQVQoz3VSuY7UQBCdnFPjPnz2+JiDtT2H51gNyw5iF1ZcQkLkJPwBv0CGyCAjR0h8AHwA0f4A/0BCQkjwqHKPjTUSwXN1V5efqt6rnnE1Bp7qQCOiXKQ1wg44154JxrX1HO1ZIwk89JqL8T1EBOO5GIYKo0hhYixuDWSdy2OJnM7j6B9ZE2PftYQ1mZbIxFWMxRWEoo/FUOFh1ce9qYMHC4vTQuAkF7iT25gFTKTrZhgtYaAEimGCD2/f4NPH93h8tkMkrxOBwjyT2IwFFhSPJ4J+UvCVRrCXgGH2aAk9KXB7FODy22f8/PEdr56dw8hrGEZu3QWPdzRQSIiM9ePIcmShzcc+5zqEiTE4SQUuv37Bn9+/8GKVospo3JnEo6WDs5mDp2sHOxr5fO5QXuDJul93fUFSlImiMxuyJ0zpc/d0h9fPN3j3covjeWkNIPEvKgf3iaQgM5YjgdXIasjjM+E0lZilJE2qkRJhTKb2uNVxbODT6PLmjbZ143lUpMlh6zwj1C7p5tajm/1q8cjNurUuV2WO9aysURVHWM+n2BCW0xKLosCS3rerRf22XVWYJIbIpF23zh5yM71AOghkHyG53TxyMYMLmnu7rwexi5qwS3RYcJhv7v8D1/wFrnQ3UTrye2UAAAAASUVORK5CYII=","aspectRatio":1.7777777777777777,"src":"/static/bb735539796f771d95a8da1745266a2c/c4ecb/nightwatch-accessibility-testing.png","srcSet":"/static/bb735539796f771d95a8da1745266a2c/57ab0/nightwatch-accessibility-testing.png 192w,\n/static/bb735539796f771d95a8da1745266a2c/f4739/nightwatch-accessibility-testing.png 384w,\n/static/bb735539796f771d95a8da1745266a2c/c4ecb/nightwatch-accessibility-testing.png 768w,\n/static/bb735539796f771d95a8da1745266a2c/4eab0/nightwatch-accessibility-testing.png 1152w,\n/static/bb735539796f771d95a8da1745266a2c/d7771/nightwatch-accessibility-testing.png 1346w","srcWebp":"/static/bb735539796f771d95a8da1745266a2c/dd090/nightwatch-accessibility-testing.webp","srcSetWebp":"/static/bb735539796f771d95a8da1745266a2c/ae504/nightwatch-accessibility-testing.webp 192w,\n/static/bb735539796f771d95a8da1745266a2c/fef30/nightwatch-accessibility-testing.webp 384w,\n/static/bb735539796f771d95a8da1745266a2c/dd090/nightwatch-accessibility-testing.webp 768w,\n/static/bb735539796f771d95a8da1745266a2c/44170/nightwatch-accessibility-testing.webp 1152w,\n/static/bb735539796f771d95a8da1745266a2c/ce310/nightwatch-accessibility-testing.webp 1346w","sizes":"(max-width: 768px) 100vw, 768px","presentationWidth":768,"presentationHeight":434},"resize":{"src":"/static/bb735539796f771d95a8da1745266a2c/c4ecb/nightwatch-accessibility-testing.png"}}}},"fields":{"slug":"/accessibility-testing-with-nightwatchjs/"},"body":"var _excluded = [\"components\"];\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"Automated web accessibility testing with Nightwatch.js and axe\",\n  \"cover\": \"./nightwatch-accessibility-testing.png\",\n  \"date\": \"2020-01-20T00:00:00.000Z\",\n  \"description\": \"There are quite a few web accessibility testing tools out there, but I thought I'd see if any could fit in with my existing automated Nightwatch tests.\",\n  \"tags\": [\"quality assurance\", \"accessibility testing\", \"software testing\", \"nightwatchjs\", \"post\"]\n};\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\nvar Embed = makeShortcode(\"Embed\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h2\", {\n    \"id\": \"web-content-accesibility-guidelines-and-the-ada\"\n  }, \"Web Content Accesibility Guidelines and the ADA\"), mdx(\"p\", null, \"Testing for compliance with web content accessibility guidelines or WCAG is becoming increasingly important. Legal precedent on how the Americans with Disabilities Act applies to websites and apps is finally catching up with the web. \"), mdx(\"p\", null, \"In the infamous Dominos Pizza case the 9th circuit court stated,\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"We agree with the district court in this case\\u2014and the many other district courts that have confronted this issue in similar contexts\\u2014that the ADA applies to Domino's website and app, which connect customers to the goods and services of Domino's physical restaurants.\")), mdx(\"p\", null, \"I'm strongly of the opinion that web content accessibility guidelines are good design principles and are good to follow regardless of the threat of legal implications. \"), mdx(\"p\", null, \"So what accessibility testing tools can we use to bake accessibility testing into our selenium test suites?\"), mdx(\"h2\", {\n    \"id\": \"nightwatchjs-and-axe-for-accessibility-testing\"\n  }, \"Nightwatch.js and Axe for Accessibility Testing\"), mdx(\"p\", null, \"Nightwatch is a great browser automation framework. Axe is an accessibility rule verification tool (it is even used Chrome Lighthouse). \"), mdx(\"p\", null, \"Wouldn't it be great if the two could be combined? Some people already thought of that so I built upon their work to do automated web accessibility testing in my existing automation suite.\"), mdx(\"p\", null, \"I found a couple npm packages that let you inject axe-core into Nightwatch as a custom command, but one didn't work with newer Chrome versions and the reporting on the other wasn't verbose enough for me.\"), mdx(\"p\", null, \"I built on that pattern with \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.npmjs.com/package/nightwatch-axe-verbose\"\n  }, \"nightwatch-axe-verbose\"), \" npm package.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-sh\"\n  }, \"npm install nightwatch-axe-verbose -s\\n\")), mdx(Embed, {\n    src: \"https://www.youtube.com/embed/nSodkqB-838\",\n    mdxType: \"Embed\"\n  }), mdx(\"h2\", {\n    \"id\": \"writing-automated-accessibility-tests\"\n  }, \"Writing Automated Accessibility Tests\"), mdx(\"p\", null, \"To write Nightwatch tests to perform accessibility assertions with nightwatch-axe-verbose you need to add to your \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"nightwatch.json\"), \" file the location of the package inside the custom commands area\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-json\"\n  }, \"\\\"custom_commands_path\\\": [\\\"./node_modules/nightwatch-axe-verbose/src/commands\\\"]\\n\")), mdx(\"p\", null, \"This will allow you to use axe assertions in your test.\"), mdx(\"p\", null, \"With the accessibility testing package added as a custom command you can use it in your Nightwatch.js tests. Here are some example accessibility tests below.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"module.exports = {\\n    '@tags': ['accessibility'],\\n    'Inaccessible site': function (browser) {\\n\\n        browser\\n            .url('https://www.w3.org/WAI/demos/bad/before/home.html')\\n            .assert.title('Welcome to CityLights! [Inaccessible Home Page]')\\n            .axeInject()\\n            .axeRun('body', {\\n                'color-contrast': { enabled: false },\\n            })\\n            .end();\\n    },\\n    'Accessible site': function (browser) {\\n\\n        browser\\n            .url('https://www.w3.org/WAI/demos/bad/after/home.html')\\n            .assert.title('Welcome to CityLights! [Accessible Home Page]')\\n            .axeInject()\\n            .axeRun('body', {\\n                rules: {}\\n            })\\n            .end();\\n    }\\n}\\n\")), mdx(\"p\", null, \".axeInject() makes the custom commands available and .axeRun() will execute all the tests in the axe-core ruleset unless customized. In the examples above, the first test provides an example of how to disable specific rules or you can specify specific rules *to run as well.\"), mdx(\"h3\", {\n    \"id\": \"useful-test-case-output\"\n  }, \"Useful test case output\"), mdx(\"p\", null, \"It is called -verbose because the package will report each passing accessibility rule run as a test case along with a count of how many controls the rule was run against. This is to ensure confidence in the results.\"), mdx(\"h4\", {\n    \"id\": \"passing-test-output\"\n  }, \"Passing test output\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-sh\"\n  }, \"\\u221A Passed [ok]: aXe rule: aria-allowed-role (2 elements checked)\\n\\u221A Passed [ok]: aXe rule: aria-hidden-body (1 elements checked)\\n\\u221A Passed [ok]: aXe rule: aria-hidden-focus (156 elements checked)\\n\\u221A Passed [ok]: aXe rule: aria-required-attr (2 elements checked)\\n\\u221A Passed [ok]: aXe rule: aria-required-children (2 elements checked)\\n...\\n\")), mdx(\"p\", null, \"Each failing test is reported per control per rule to ensure you get a complete picture of what is violating WCAG accessibility on your site so you can fix it all at once. \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Other libraries I was looking would exit on first failure, hiding downstream issues.\")), mdx(\"h4\", {\n    \"id\": \"failing-test-output\"\n  }, \"Failing test output\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-sh\"\n  }, \"\\xD7 Failed [fail]: (aXe rule: heading-order - Heading levels should only increase by one  \\n        In element: h5\\n\\xD7 Failed [fail]: (aXe rule: image-alt - Images must have alternate text\\n        In element: .small-logo\\n\\xD7 Failed [fail]: (aXe rule: label - Form elements must have labels\\n        In element: #SearchInput)\\n\")), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/reallymello/nightwatchTutorials/tree/master/accessibilityExample\"\n  }, \"Nightwatch accessible test project on my GitHub\")));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"id":"dce55945-37a4-54cd-9760-44deaccb9a6e"}},"staticQueryHashes":["1961101537","2542493696"]}